package com.interview.three;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.AnnotationConfigUtils;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.GenericApplicationContext;

/**
 * 学习注解 Configuration注解原理并，了解其实现
 */
@Slf4j
public class TestConfiguration {
    public static void main(String[] args) {
        GenericApplicationContext context = new GenericApplicationContext();
        AnnotationConfigUtils.registerAnnotationConfigProcessors(context.getDefaultListableBeanFactory());
        context.registerBean("myConfig", MyConfig.class);
        context.refresh();
        System.out.println(context.getBean(MyConfig.class).getClass());
    }


    @Configuration(proxyBeanMethods = true)
    // 注意点1：配置类其实相当于一个工厂，标注@Bean注解的方法相当于工厂方法
    static class MyConfig {
        // 注意点2：@Bean 不支持方法重载，如果多个重载方法，仅有一个能入选为工厂方法
        // 注意点3：@Configuration默认会为标注的类生成代理，其母的是保证@Bean方法相互调用，依然可以保证单例性
        @Bean
        public Bean1 bean1() {
            System.out.println("bean1()");
            System.out.println(bean2());
            System.out.println(bean2());
            System.out.println(bean2());
            return new Bean1();
        }

        @Value("${java.class.version}") 
        private String a;



        @Bean
        public Bean2 bean2() {
            log.error("在配置中，使用 Spring后置处理器，没有设置为static，能否使用@value呢：{}",a);
            System.out.println("bean2()");
            return new Bean2();
        }
    }

    static class Bean1 {

    }

    static class Bean2 {

    }

    static class Bean3 {

    }
}
